﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YArchitech.ProgressBar;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using YArchitech.Revit.RevitExtension;
using HYElectricKernel;
using TopologySearch;

namespace HYRElectric.WirePlace
{
	internal class CreateConduitFunction
	{
		public CreateConduitFunction(UIDocument uiDoc)
		{
			this.uiDoc = uiDoc;
			this.m_doc = uiDoc.Document;
		}

		public CreateConduitFunction(ExternalCommandData cmdData)
		{
			this.m_cmdData = cmdData;
			this.uiDoc = cmdData.Application.ActiveUIDocument;
			this.m_doc = this.uiDoc.Document;
		}

		public void CmdCreateConduitByWire(UIDocument uiDoc, DlgCreateConduitConfig dlg)
		{
			List<Wire> list = this.SelectWire(uiDoc);
			if (list.Count == 0)
			{
				return;
			}
			this.GetRelationData();
			this.GetConduitDis();
			List<WireStruct> list2 = new List<WireStruct>();
			List<Wire> list3 = new List<Wire>();
			foreach (Wire wire in list)
			{
				bool flag = false;
				foreach (Wire wire2 in list3)
				{
					if (wire.Id.Equals(wire2.Id))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					WireStruct wireStruct = new WireStruct(wire);
					list2.Add(wireStruct);
					list3.AddRange(wireStruct.wireItems());
				}
			}
			this.getAllConduitAndFitting();
			Transaction transaction = new Transaction(this.m_doc, "CreateConduitByWire");
			transaction.Start();
			SubTransaction subTransaction = new SubTransaction(this.m_doc);
			subTransaction.Start();
			FamilySymbol conduitFittings = this.GetConduitFittings(this.m_doc, "线管接线盒-四通");
			UnifiedModified.ActivateFamilySymbol(conduitFittings);
			FamilyInstance elem = this.m_doc.Create.NewFamilyInstance(XYZ.Zero, conduitFittings, 0);
			this.m_dThick = elem.GetParameter("高度").AsDouble();
			this.m_dWide = elem.GetParameter("宽度").AsDouble();
			subTransaction.RollBack();
			if (CreateConduitFunction._hWndRevit == null)
			{
                CreateConduitFunction._hWndRevit = new HYCodeBase.WinForm.WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			ProgressBarForm progressBarForm = new ProgressBarForm(list2.Count, ProgressBarStyle.Blocks, true);
			progressBarForm.Show(CreateConduitFunction._hWndRevit);
			try
			{
				int num = 0;
				foreach (WireStruct wireStruct2 in list2)
				{
					progressBarForm.RefreshProgressBar();
					if (progressBarForm.m_stopTag)
					{
						break;
					}
					List<Wire> list4 = wireStruct2.wireItems();
					bool flag2 = false;
					WireParams wireParams = new WireParams();
					InstallType installType = dlg.getInstallType();
					if (!this.GetWireProperties(this.m_doc, list4[0], ref wireParams) || dlg.getCreateType())
					{
						wireParams.ConduitDiameter = dlg.getDiameter() / 304.8;
						wireParams.ConduitTypeID = dlg.getConduitTypeID();
						installType = dlg.getInstallType();
						flag2 = true;
					}
					else
					{
						string layMode = wireParams.LayMode;
						if (layMode == null)
						{
							installType = InstallType.CC;
						}
						else if (layMode.Equals("CC"))
						{
							installType = InstallType.CC;
						}
						else if (layMode.Equals("CE"))
						{
							installType = InstallType.CE;
						}
						else if (layMode.Equals("SCE"))
						{
							installType = InstallType.SCE;
						}
						else if (layMode.Equals("WC"))
						{
							installType = InstallType.WC;
						}
						else if (layMode.Equals("WS"))
						{
							installType = InstallType.WS;
						}
						else if (layMode.Equals("FC"))
						{
							installType = InstallType.FC;
						}
						else
						{
							installType = InstallType.CC;
						}
					}
					List<RouterLine> list5 = new List<RouterLine>();
					Element element = wireStruct2.startElement();
					Element element2 = wireStruct2.endElement();
					new List<Curve>();
					new List<Wire>();
					if (element == null && element2 == null)
					{
						list5 = this.GetNoneOrOneElementLines(null, wireStruct2);
					}
					else if (element == null)
					{
						list5 = this.GetNoneOrOneElementLines(element2, wireStruct2);
					}
					else if (element2 == null)
					{
						list5 = this.GetNoneOrOneElementLines(element, wireStruct2);
					}
					else
					{
						list5 = this.getWireRouteLines(wireStruct2, installType);
					}
					if (list5.Count >= 0)
					{
						if (installType == InstallType.CE || installType == InstallType.WS || installType == InstallType.SCE)
						{
							list5 = this.processConduitRouterLines(list5);
						}
						this.usedConduits.Clear();
						this.CreateConduits(list5, wireStruct2, wireParams, installType);
						if (flag2)
						{
							foreach (Wire elem2 in wireStruct2.wireItems())
							{
								elem2.GetParameter("敷设方式").Set(dlg.getStringInstallType());
								elem2.GetParameter("管径").Set(wireParams.ConduitDiameter);
								elem2.GetParameter("线管类型").Set(dlg.getStringConduitType());
							}
						}
						num += list5.Count;
						this.breakConduitByFitting();
						this.MergeSameConduit();
					}
				}
				if (num != 0)
				{
					string text = "根据选择导线生成线管" + num.ToString() + "条！";
					if (this.m_isImproveDefultHigh)
					{
						text += "\n由于按照设置高度生成线管会导致某些线管和设备重合，系统已根据构件位置自动对管线敷设高度进行调整。";
					}
					TaskDialog.Show("提示", text);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				progressBarForm.Close();
				transaction.RollBack();
			}
		}

		public bool GetBaseDatas()
		{
			this.m_allLinkDocs = CreateConduitFunction.GetLinkDocs(this.m_doc);
			this.getALLDocWaLLs();
			this.getALLDocCelings();
			this.getALLDocFloor();
			this.getALLDocStructuralFramings();
			this.m_roomList.Clear();
			this.GetRoomDataInfos(ref this.m_roomList);
			if (this.m_wallList.Count < 1)
			{
				string text = string.Format("当前视图或链接文件中没有墙！ ", Array.Empty<object>());
				TaskDialog.Show("提示", text);
				return false;
			}
			if (this.m_FloorList.Count < 1)
			{
				string text2 = string.Format("当前视图或链接文件中没有楼板！ ", Array.Empty<object>());
				TaskDialog.Show("提示", text2);
				return false;
			}
			if (this.m_roomList.Count < 1)
			{
				string text3 = string.Format("当前视图或链接文件中没有可以构成的房间！ ", Array.Empty<object>());
				TaskDialog.Show("提示", text3);
				return false;
			}
			return true;
		}

		private void GetRelationData()
		{
			this.m_RelationDataList.Clear();
			this.m_RelationDataList = DlgSetRelationMap.ReadXml();
		}

		private void GetConduitDis()
		{
			string text = null;
			string text2 = null;
			DlgSetSCEHigh.ReadXml(ref text, ref text2);
			if (text != null && text != "")
			{
				this.m_TopCelingDis = Convert.ToInt32(text);
			}
			if (text2 != null && text2 != "")
			{
				this.m_BotFloorDis = Convert.ToInt32(text2);
			}
			int highValue = DlgSetFCHigh.GetHighValue();
			if (-1 != highValue)
			{
				this.m_HighGroundDis = highValue;
			}
		}

		private static List<Document> GetLinkDocs(Document doc)
		{
			List<Document> list = new List<Document>();
			try
			{
				foreach (RevitLinkInstance revitLinkInstance in ((IEnumerable<RevitLinkInstance>)new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)).Cast<RevitLinkInstance>().ToList<RevitLinkInstance>()))
				{
					list.Add(revitLinkInstance.GetLinkDocument());
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			return list;
		}

		private List<RouterLine> processConduitRouterLines(List<RouterLine> routerLineList)
		{
			for (int i = 0; i < routerLineList.Count; i++)
			{
				Curve curve = routerLineList[i].curve;
				XYZ xyz = curve.GetEndPoint(1) - curve.GetEndPoint(0);
				if (!xyz.Normalize().IsAlmostEqualTo(XYZ.BasisZ) && !xyz.Normalize().IsAlmostEqualTo(-XYZ.BasisZ))
				{
					List<RouterLine> collection = new List<RouterLine>();
					if (this.getGirderLines(routerLineList[i], out collection))
					{
						routerLineList.RemoveAt(i);
						routerLineList.InsertRange(i, collection);
						i--;
					}
				}
			}
			return routerLineList;
		}

		private bool getGirderLines(RouterLine routerline, out List<RouterLine> curveList)
		{
			Curve curve = routerline.curve;
			bool result = false;
			curveList = new List<RouterLine>();
			foreach (FamilyInstance familyInstance in this.m_GirderList)
			{
				if (familyInstance != null)
				{
					Curve curve2 = (familyInstance.Location as LocationCurve).Curve;
					XYZ xyz = null;
					if (this.isCross(curve, curve2, ref xyz))
					{
						List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(familyInstance.get_Geometry(new Options
						{
							View = this.m_doc.ActiveView
						}));
						XYZ vec = null;
						foreach (GeometryObject geometryObject in geometryObjectArray)
						{
							GeometryInstance geometryInstance = geometryObject as GeometryInstance;
							if (geometryInstance != null)
							{
								Transform transform = geometryInstance.Transform;
								Curve curve3 = curve2.CreateTransformed(transform.Inverse);
								vec = curve3.GetEndPoint(1) - curve3.GetEndPoint(0);
							}
						}
						double width = 0.0;
						double num = 0.0;
						this.GetGirderWidthAndHigh(familyInstance, vec, ref width, ref num);
						if (curve.GetEndPoint(0).Z < curve2.GetEndPoint(0).Z && curve.GetEndPoint(0).Z > curve2.GetEndPoint(0).Z - num)
						{
							curveList = this.CalculateNewCurve(routerline, curve2, width, num);
							if (curveList.Count > 2)
							{
								result = true;
								break;
							}
							break;
						}
					}
				}
			}
			return result;
		}

		private List<RouterLine> CalculateNewCurve(RouterLine routerline, Curve girderCurve, double width, double high)
		{
			Curve curve = routerline.curve;
			List<RouterLine> list = new List<RouterLine>();
			XYZ hyendPoint = girderCurve.GetEndPoint(0);
			XYZ hyendPoint2 = girderCurve.GetEndPoint(1);
			double num = hyendPoint.Z - high;
			XYZ xyz = (hyendPoint2 - hyendPoint).Normalize();
			XYZ xyz2 = hyendPoint + width / 2.0 * xyz.CrossProduct(XYZ.BasisZ);
			XYZ xyz3 = hyendPoint2 + width / 2.0 * xyz.CrossProduct(XYZ.BasisZ);
			Line curve2 = Line.CreateBound(xyz2, xyz3);
			XYZ xyz4 = hyendPoint - width / 2.0 * xyz.CrossProduct(XYZ.BasisZ);
			XYZ xyz5 = hyendPoint2 - width / 2.0 * xyz.CrossProduct(XYZ.BasisZ);
			Line curve3 = Line.CreateBound(xyz4, xyz5);
			XYZ xyz6 = null;
			XYZ xyz7 = null;
			XYZ hyendPoint3 = curve.GetEndPoint(0);
			XYZ hyendPoint4 = curve.GetEndPoint(1);
			if (hyendPoint3.Z - num < this.m_dThick)
			{
				return list;
			}
			XYZ xyz8 = (hyendPoint4 - hyendPoint3).Normalize();
			List<XYZ> list2 = new List<XYZ>();
			if (this.isCross(curve2, curve, ref xyz6) && this.isCross(curve3, curve, ref xyz7))
			{
				list2.Add(hyendPoint3);
				if (hyendPoint3.DistanceTo(xyz6) < hyendPoint3.DistanceTo(xyz7))
				{
					xyz6 -= this.m_dWide / 2.0 * xyz8;
					list2.Add(new XYZ(xyz6.X, xyz6.Y, hyendPoint3.Z));
					XYZ item = new XYZ(xyz6.X, xyz6.Y, num - this.m_dThick / 2.0);
					list2.Add(item);
					xyz7 += this.m_dWide / 2.0 * xyz8;
					item = new XYZ(xyz7.X, xyz7.Y, num - this.m_dThick / 2.0);
					list2.Add(item);
					list2.Add(new XYZ(xyz7.X, xyz7.Y, hyendPoint4.Z));
				}
				else
				{
					xyz7 -= this.m_dWide / 2.0 * xyz8;
					list2.Add(new XYZ(xyz7.X, xyz7.Y, hyendPoint3.Z));
					XYZ item2 = new XYZ(xyz7.X, xyz7.Y, num - this.m_dThick / 2.0);
					list2.Add(item2);
					xyz6 += this.m_dWide / 2.0 * xyz8;
					item2 = new XYZ(xyz6.X, xyz6.Y, num - this.m_dThick / 2.0);
					list2.Add(item2);
					list2.Add(new XYZ(xyz6.X, xyz6.Y, hyendPoint4.Z));
				}
				list2.Add(hyendPoint4);
			}
			if (list2.Count > 1)
			{
				for (int i = 0; i < list2.Count - 1; i++)
				{
					RouterLine routerLine = new RouterLine();
					Line curve4 = Line.CreateBound(list2[i], list2[i + 1]);
					routerLine.curve = curve4;
					if (2 == i)
					{
						routerLine.vecXyz = XYZ.BasisZ;
					}
					else
					{
						routerLine.vecXyz = routerline.vecXyz;
					}
					list.Add(routerLine);
				}
			}
			return list;
		}

		private bool isCross(Curve curve1, Curve curve2, ref XYZ pt)
		{
			bool result = false;
			XYZ xyz = new XYZ(curve1.GetEndPoint(0).X, curve1.GetEndPoint(0).Y, 0.0);
			XYZ xyz2 = new XYZ(curve1.GetEndPoint(1).X, curve1.GetEndPoint(1).Y, 0.0);
			Curve curve3 = Line.CreateBound(xyz, xyz2);
			XYZ xyz3 = new XYZ(curve2.GetEndPoint(0).X, curve2.GetEndPoint(0).Y, 0.0);
			XYZ xyz4 = new XYZ(curve2.GetEndPoint(1).X, curve2.GetEndPoint(1).Y, 0.0);
			Line line = Line.CreateBound(xyz3, xyz4);
			IntersectionResultArray intersectionResultArray;
            if (curve3.Intersect(line, out intersectionResultArray) != (SetComparisonResult)4 && intersectionResultArray.Size == 1)
			{
				pt = intersectionResultArray.get_Item(0).XYZPoint;
				result = true;
			}
			return result;
		}

		private void GetGirderWidthAndHigh(FamilyInstance column, XYZ vec, ref double width, ref double high)
		{
			Options options = new Options();
			options.View = this.m_doc.ActiveView;
			GeometryElement geometryElement = column.Symbol.get_Geometry(options);
			if (null == geometryElement)
			{
				return;
			}
			try
			{
				foreach (GeometryObject geometryObject in geometryElement)
				{
					if (!(geometryObject.GetType() != typeof(Solid)))
					{
						Solid solid = geometryObject as Solid;
						if (solid != null)
						{
							new List<Curve>();
							foreach (object obj in solid.Faces)
							{
								PlanarFace planarFace = ((Face)obj) as PlanarFace;
								XYZ xyz = vec.Normalize();
								if (null != planarFace && planarFace.FaceNormal().IsAlmostEqualTo(xyz))
								{
									BoundingBoxUV boundingBox = planarFace.GetBoundingBox();
									high = boundingBox.Max.U - boundingBox.Min.U;
									width = boundingBox.Max.V - boundingBox.Min.V;
									break;
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void MergeSameConduit()
		{
			for (int i = 0; i < this.m_oldConduits.Count; i++)
			{
				Curve curve = (this.m_oldConduits[i].Location as LocationCurve).Curve;
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				for (int j = 0; j < this.m_oldConduits.Count; j++)
				{
					if (i < j)
					{
						Curve curve2 = (this.m_oldConduits[j].Location as LocationCurve).Curve;
						XYZ hyendPoint3 = curve2.GetEndPoint(0);
						XYZ hyendPoint4 = curve2.GetEndPoint(1);
						XYZ xyz = null;
						XYZ xyz2 = null;
						if (Geometry.IsOverlapOfTwoLine(hyendPoint, hyendPoint2, hyendPoint3, hyendPoint4, ref xyz, ref xyz2, this.m_dWide * 2.0 / 3.0) == Geometry.OverlapType._OT_Equality)
						{
							List<Connector> conduitConnectors = RevitUtils.GetConduitConnectors(this.m_oldConduits[j]);
							List<Connector> list = new List<Connector>();
							foreach (Connector connector in conduitConnectors)
							{
								ConnectorSet allRefs = connector.AllRefs;
								if (allRefs.Size > 0)
								{
									foreach (object obj in allRefs)
									{
										Connector connector2 = (Connector)obj;
										if (connector2.Owner is FamilyInstance)
										{
											list.Add(connector2);
										}
									}
								}
							}
							if (list.Count == 2)
							{
								string wireid = this.m_oldConduits[i].GetParameter("所含导线").AsString();
								this.SetConduitParameters(this.m_doc, this.m_oldConduits[j], wireid, true);
								this.m_doc.DeleteElement(this.m_oldConduits[i]);
								this.m_oldConduits.RemoveAt(i);
								i--;
								break;
							}
							if (list.Count == 1)
							{
								List<Connector> conduitConnectors2 = RevitUtils.GetConduitConnectors(this.m_oldConduits[i]);
								List<FamilyInstance> list2 = new List<FamilyInstance>();
								foreach (Connector connector3 in conduitConnectors2)
								{
									ConnectorSet allRefs2 = connector3.AllRefs;
									if (allRefs2.Size > 0)
									{
										foreach (object obj2 in allRefs2)
										{
											Connector connector4 = (Connector)obj2;
											Element owner = connector4.Owner;
											if (owner is FamilyInstance)
											{
												connector4.DisconnectFrom(connector3);
												list2.Add(owner as FamilyInstance);
											}
										}
									}
								}
								if (list2.Count > 0)
								{
									XYZ vecConduit = list[0].Origin - (list2[0].Location as LocationPoint).Point;
									double diameter = this.m_oldConduits[j].GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).AsDouble();
									this.connectConduitConnector(this.m_oldConduits[j], vecConduit, list2[0], diameter);
								}
								string wireid2 = this.m_oldConduits[i].GetParameter("所含导线").AsString();
								this.SetConduitParameters(this.m_doc, this.m_oldConduits[j], wireid2, true);
								this.m_doc.DeleteElement(this.m_oldConduits[i]);
								this.m_oldConduits.RemoveAt(i);
								i--;
								break;
							}
							string wireid3 = this.m_oldConduits[j].GetParameter("所含导线").AsString();
							this.SetConduitParameters(this.m_doc, this.m_oldConduits[i], wireid3, true);
							this.m_doc.DeleteElement(this.m_oldConduits[j]);
							this.m_oldConduits.RemoveAt(j);
							j--;
						}
					}
				}
			}
		}

		private void breakConduitByFitting()
		{
			int num = 0;
			try
			{
				for (int i = 0; i < this.m_oldConduits.Count; i++)
				{
					num++;
					if (100 == num)
					{
						num = 0;
					}
					List<FamilyInstance> list = new List<FamilyInstance>();
					Conduit conduit = this.m_oldConduits[i];
					Curve curve = (conduit.Location as LocationCurve).Curve;
					foreach (FamilyInstance familyInstance in this.m_oldFittings)
					{
						XYZ point = (familyInstance.Location as LocationPoint).Point;
						if (curve.Distance(point) < CreateConduitFunction.approximate && !curve.GetEndPoint(0).IsAlmostEqualTo(point, CreateConduitFunction.approximate) && !curve.GetEndPoint(1).IsAlmostEqualTo(point, CreateConduitFunction.approximate))
						{
							list.Add(familyInstance);
						}
					}
					if (list.Count > 0)
					{
						int num2 = this.createNewConduitByfitting(i + 1, conduit, list);
						this.m_doc.DeleteElement(this.m_oldConduits[i]);
						this.m_oldConduits.RemoveAt(i);
						i = i + num2 - 1;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private int createNewConduitByfitting(int nindex, Conduit conduit, List<FamilyInstance> fittingList)
		{
			List<Connector> conduitConnectors = RevitUtils.GetConduitConnectors(conduit);
			List<Connector> list = new List<Connector>();
			List<FamilyInstance> list2 = new List<FamilyInstance>();
			foreach (Connector connector in conduitConnectors)
			{
				ConnectorSet allRefs = connector.AllRefs;
				if (allRefs.Size > 0)
				{
					foreach (object obj in allRefs)
					{
						Connector connector2 = (Connector)obj;
						Element owner = connector2.Owner;
						if (owner is FamilyInstance)
						{
							connector2.DisconnectFrom(connector);
							list.Add(connector2);
							list2.Add(owner as FamilyInstance);
						}
					}
				}
			}
			List<FamilyInstance> list3 = new List<FamilyInstance>();
			if (list.Count > 0)
			{
				list3 = this.sortFittings(list[0], fittingList);
				XYZ origin = list[0].Origin;
				Connector connector3 = list[0];
				if (2 == list.Count)
				{
					this.createConduits(list2[0], list3, list2[1], conduit, nindex);
				}
				else
				{
					this.createConduits(list2[0], list3, null, conduit, nindex);
				}
			}
			else
			{
				this.createConduits(null, list3, null, conduit, nindex);
			}
			return list3.Count + 1;
		}

		private void createConduits(FamilyInstance fittingStart, List<FamilyInstance> fittingList, FamilyInstance fittingEnd, Conduit conduit, int index)
		{
			List<Connector> conduitConnectors = RevitUtils.GetConduitConnectors(conduit);
			string wireid = conduit.GetParameter("所含导线").AsString();
			ElementId typeId = conduit.GetTypeId();
			double num = conduit.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).AsDouble();
			XYZ xyz;
			if (fittingStart != null)
			{
				xyz = (fittingStart.Location as LocationPoint).Point;
			}
			else
			{
				xyz = conduitConnectors[0].Origin;
			}
			if (fittingEnd != null)
			{
				XYZ xyz2 = (fittingEnd.Location as LocationPoint).Point;
			}
			else
			{
				XYZ xyz2 = conduitConnectors[1].Origin;
			}
			int count = fittingList.Count;
			if (count > 0)
			{
				XYZ xyz2;
				for (int i = 0; i < count; i++)
				{
					xyz2 = (fittingList[i].Location as LocationPoint).Point;
					Conduit conduit2 = Conduit.Create(this.m_doc, typeId, xyz, xyz2, this.m_doc.ActiveView.GenLevel.Id);
					conduit2.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(num);
					this.SetConduitParameters(this.m_doc, conduit2, wireid, true);
					this.m_oldConduits.Insert(index, conduit2);
					index++;
					XYZ vecConduit = xyz - xyz2;
					XYZ vecConduit2 = xyz2 - xyz;
					if (i == 0)
					{
						if (fittingStart != null)
						{
							this.connectConduitConnector(conduit2, vecConduit2, fittingStart, num);
							this.SetFittingParameters(this.m_doc, fittingStart, wireid, true);
						}
						this.connectConduitConnector(conduit2, vecConduit, fittingList[i], num);
						this.SetFittingParameters(this.m_doc, fittingList[i], wireid, true);
					}
					else
					{
						this.connectConduitConnector(conduit2, vecConduit2, fittingList[i - 1], num);
						this.SetFittingParameters(this.m_doc, fittingList[i - 1], wireid, true);
						this.connectConduitConnector(conduit2, vecConduit, fittingList[i], num);
						this.SetFittingParameters(this.m_doc, fittingList[i], wireid, true);
					}
					xyz = xyz2;
				}
				if (fittingEnd != null)
				{
					xyz2 = (fittingEnd.Location as LocationPoint).Point;
				}
				else
				{
					xyz2 = conduitConnectors[1].Origin;
				}
				Conduit conduit3 = Conduit.Create(this.m_doc, typeId, xyz, xyz2, this.m_doc.ActiveView.GenLevel.Id);
				conduit3.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(num);
				this.SetConduitParameters(this.m_doc, conduit3, wireid, true);
				this.m_oldConduits.Insert(index, conduit3);
				XYZ vecConduit3 = xyz - xyz2;
				XYZ vecConduit4 = xyz2 - xyz;
				RevitUtils.GetConduitConnectors(conduit3);
				if (fittingEnd != null)
				{
					this.connectConduitConnector(conduit3, vecConduit3, fittingEnd, num);
					this.SetFittingParameters(this.m_doc, fittingEnd, wireid, true);
				}
				this.connectConduitConnector(conduit3, vecConduit4, fittingList[count - 1], num);
				this.SetFittingParameters(this.m_doc, fittingList[count - 1], wireid, true);
			}
		}

		private List<FamilyInstance> sortFittings(Connector connector, List<FamilyInstance> fittingList)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			List<double> list2 = new List<double>();
			XYZ origin = connector.Origin;
			for (int i = 0; i < fittingList.Count; i++)
			{
				XYZ point = (fittingList[i].Location as LocationPoint).Point;
				double num = connector.Origin.DistanceTo(point);
				int j;
				for (j = 0; j < list2.Count; j++)
				{
					if (num < list2[j])
					{
						list2.Insert(j, num);
						list.Insert(j, fittingList[i]);
						break;
					}
				}
				if (i == 0 || j == list2.Count)
				{
					list2.Add(num);
					list.Add(fittingList[i]);
				}
			}
			return list;
		}

		private string MergeExtWireId(string oldWireId, string wireId)
		{
			if (oldWireId == null || "" == oldWireId)
			{
				return wireId;
			}
			if (-1 != oldWireId.IndexOf(wireId))
			{
				return oldWireId;
			}
			return oldWireId + "|" + wireId;
		}

		private string RemoveExtWireId(string oldWireId, string wireId)
		{
			string text = null;
			string[] array = oldWireId.Split(new char[]
			{
				'|'
			});
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i];
				if (!text2.Equals(wireId))
				{
					text += text2;
					if (i != array.Length - 1)
					{
						text += "|";
					}
				}
			}
			return text;
		}

		private List<RouterLine> GetNoneOrOneElementLines(Element element, WireStruct wire)
		{
			List<RouterLine> list = new List<RouterLine>();
			List<XYZ> list2 = wire.wirePoints();
			XYZ xyz = list2[0];
			XYZ xyz2 = list2[list2.Count - 1];
			int num = 0;
			XYZ xyz3;
			XYZ xyz4;
			if (element != null)
			{
				xyz3 = RevitUtils.GetDeviceConnector(element).Origin;
				num = this.GetEquipConnectDirection(element);
				if (xyz3.DistanceTo(xyz) < xyz3.DistanceTo(xyz2))
				{
					xyz4 = xyz2;
				}
				else
				{
					xyz4 = xyz;
					list2.Reverse();
				}
			}
			else
			{
				xyz3 = xyz;
				xyz4 = xyz2;
			}
			bool flag = true;
			XYZ xyz5;
			if (2 != num)
			{
				if (xyz3.Z < xyz4.Z)
				{
					xyz5 = new XYZ(xyz3.X, xyz3.Y, xyz4.Z);
					flag = true;
				}
				else
				{
					xyz5 = new XYZ(xyz4.X, xyz4.Y, xyz3.Z);
					flag = false;
				}
			}
			else
			{
				xyz5 = new XYZ(xyz4.X, xyz4.Y, xyz3.Z);
			}
			if (!xyz3.IsAlmostEqualTo(xyz5, CreateConduitFunction.approximate) && flag)
			{
				list.Add(new RouterLine
				{
					curve = Line.CreateBound(xyz3, xyz5),
					vecXyz = null
				});
			}
			for (int i = 0; i < list2.Count - 1; i++)
			{
				XYZ xyz6 = new XYZ(list2[i].X, list2[i].Y, xyz5.Z);
				XYZ xyz7 = new XYZ(list2[i + 1].X, list2[i + 1].Y, xyz5.Z);
				list.Add(new RouterLine
				{
					curve = Line.CreateBound(xyz6, xyz7),
					vecXyz = null
				});
			}
			if (!xyz5.IsAlmostEqualTo(xyz4, CreateConduitFunction.approximate) && !flag)
			{
				list.Add(new RouterLine
				{
					curve = Line.CreateBound(xyz5, xyz4),
					vecXyz = null
				});
			}
			return list;
		}

		private List<Wire> SelectWire(UIDocument uiDoc)
		{
			List<Wire> result = new List<Wire>();
			RevitVersionFuncs.ClearSelection(uiDoc.Selection);
            List<Reference> list = uiDoc.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new ElectricDim.WireFilter(), "请选择要生成线管的导线").ToList<Reference>();
			if (list.Count == 0)
			{
				TaskDialog.Show("盈建科提示", "未选中导线，请重新选择。");
				return result;
			}
			return (from pickObj in list
			select uiDoc.Document.GetElement(pickObj.ElementId) as Wire).ToList<Wire>();
		}

		private void DeleteExistConduit(List<Wire> wireList)
		{
			foreach (Wire wire in wireList)
			{
				string text = wire.Id.ToString();
				for (int i = 0; i < this.m_oldConduits.Count; i++)
				{
					Parameter parameter = this.m_oldConduits[i].GetParameter("所含导线");
					if (parameter != null)
					{
						string text2 = parameter.AsString();
						if (text2 != null && !text2.Equals("") && -1 != text2.IndexOf(text))
						{
							string text3 = this.deleteStringForNewOne(text2, text);
							if (text3 == null)
							{
								this.m_doc.DeleteElement(this.m_oldConduits[i]);
								this.m_oldConduits.RemoveAt(i);
								i--;
							}
							else
							{
								this.SetConduitParameters(this.m_doc, this.m_oldConduits[i], text3, false);
							}
						}
					}
				}
				for (int j = 0; j < this.m_oldFittings.Count; j++)
				{
					Parameter parameter2 = this.m_oldFittings[j].GetParameter("所含导线");
					if (parameter2 != null)
					{
						string text4 = parameter2.AsString();
						if (text4 != null && !text4.Equals("") && -1 != text4.IndexOf(text))
						{
							string text5 = this.deleteStringForNewOne(text4, text);
							if (text5 == null)
							{
								this.m_doc.DeleteElement(this.m_oldFittings[j]);
								this.m_oldFittings.RemoveAt(j);
								j--;
							}
							else
							{
								this.SetFittingParameters(this.m_doc, this.m_oldFittings[j], text5, false);
							}
						}
					}
				}
			}
		}

		private string deleteStringForNewOne(string ids, string id)
		{
			string text = null;
			string[] array = ids.Split(new char[]
			{
				'|'
			});
			for (int i = 0; i < array.Length; i++)
			{
				if (-1 == array[i].IndexOf(id))
				{
					text = this.MergeExtWireId(text, array[i]);
				}
			}
			return text;
		}

		private void getAllConduitAndFitting()
		{
			this.m_oldConduits.Clear();
			this.m_oldFittings.Clear();
			List<Element> list = RevitFilter.GetElementsOfType(this.m_doc, typeof(Conduit)).ToList<Element>();
			IList<Element> list2 = new FilteredElementCollector(this.m_doc).OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_ConduitFitting).ToElements();
			foreach (Element element in list)
			{
				Conduit item = element as Conduit;
				this.m_oldConduits.Add(item);
			}
			foreach (Element element2 in list2)
			{
				FamilyInstance item2 = element2 as FamilyInstance;
				this.m_oldFittings.Add(item2);
			}
		}

		private InstallType getInstallTypeByElement(int dricS, int dricE, Wall wallstrat, Wall wallend, InstallType installpos)
		{
			if (dricS == 0 && dricE == 0)
			{
				if (installpos != InstallType.CC && InstallType.CE != installpos && InstallType.SCE != installpos)
				{
					installpos = InstallType.CC;
				}
			}
			else if ((dricS == 0 && dricE == 1) || (dricS == 1 && dricE == 0))
			{
				if (InstallType.FC == installpos)
				{
					installpos = InstallType.CC;
				}
			}
			else if (dricS == 1 && dricE == 1)
			{
				if (wallend.Equals(wallstrat) && InstallType.WS != installpos)
				{
					installpos = InstallType.WC;
				}
			}
			else if ((dricS == 1 && dricE == 2) || (dricS == 2 && dricE == 1))
			{
				if (InstallType.WS != installpos && InstallType.WC != installpos)
				{
					installpos = InstallType.FC;
				}
			}
			else if (dricS == 2 && dricE == 2)
			{
				installpos = InstallType.FC;
			}
			else
			{
				installpos = InstallType.CC;
			}
			return installpos;
		}

		private List<RouterLine> getWireRouteLines(WireStruct wire, InstallType installpos)
		{
			Element element = wire.startElement();
			Element element2 = wire.endElement();
			List<Curve> list = new List<Curve>();
			List<RouterLine> list2 = new List<RouterLine>();
			int equipConnectDirection = this.GetEquipConnectDirection(element);
			int equipConnectDirection2 = this.GetEquipConnectDirection(element2);
			double num;
			Wall nearestWall = this.GetNearestWall(element, out num);
			double num2;
			Wall nearestWall2 = this.GetNearestWall(element2, out num2);
			installpos = this.getInstallTypeByElement(equipConnectDirection, equipConnectDirection2, nearestWall, nearestWall2, installpos);
			if (installpos == InstallType.CC)
			{
				if (equipConnectDirection == 2 || equipConnectDirection2 == 2 || (equipConnectDirection == 1 && equipConnectDirection2 == 1 && nearestWall2.Equals(nearestWall)))
				{
					string text = string.Format("起始设备的安装方式无法通过楼顶板中心！ ", Array.Empty<object>());
					TaskDialog.Show("提示", text);
				}
				else
				{
					list = this.GetCcAndCeTypeLines(wire, installpos);
				}
			}
			else if (InstallType.SCE == installpos || InstallType.CE == installpos)
			{
				if (equipConnectDirection == 2 || equipConnectDirection2 == 2 || (equipConnectDirection == 1 && equipConnectDirection2 == 1 && nearestWall2.Equals(nearestWall)))
				{
					string text2 = string.Format("起始设备的安装方式无法紧贴楼顶板！ ", Array.Empty<object>());
					TaskDialog.Show("提示", text2);
				}
				else if ((equipConnectDirection == 0 && equipConnectDirection2 == 0) || (equipConnectDirection2 == 1 && equipConnectDirection == 1))
				{
					list = this.GetCcAndCeTypeLines(wire, installpos);
				}
				else
				{
					Element equipment;
					if (equipConnectDirection == 1)
					{
						equipment = element;
					}
					else
					{
						equipment = element2;
					}
					double high;
					if (this.getFloorOrCelingLevel(equipment, installpos, out high))
					{
						list2 = this.GetLinesAlongWall(nearestWall, element, nearestWall2, element2, installpos, high);
					}
				}
			}
			else if (InstallType.FC == installpos)
			{
				if (equipConnectDirection == 0 || equipConnectDirection2 == 0)
				{
					string text3 = string.Format("起点或终止设备为吊装！ ", Array.Empty<object>());
					TaskDialog.Show("提示", text3);
				}
				else
				{
					list = this.GetCcAndCeTypeLines(wire, installpos);
				}
			}
			else if (InstallType.WC == installpos || InstallType.WS == installpos)
			{
				if (equipConnectDirection != 1 && equipConnectDirection2 != 1)
				{
					list = this.GetCcAndCeTypeLines(wire, InstallType.CC);
				}
				else if ((equipConnectDirection == 1 && equipConnectDirection2 == 0) || (equipConnectDirection == 0 && equipConnectDirection2 == 1))
				{
					Element equipment2;
					if (equipConnectDirection == 1)
					{
						equipment2 = element;
					}
					else
					{
						equipment2 = element2;
					}
					double high2;
					if (this.getFloorOrCelingLevel(equipment2, InstallType.CC, out high2))
					{
						list2 = this.GetLinesAlongWall(nearestWall, element, nearestWall2, element2, installpos, high2);
					}
				}
				else if ((equipConnectDirection == 1 && equipConnectDirection2 == 2) || (equipConnectDirection == 2 && equipConnectDirection2 == 1))
				{
					Element equipment3;
					if (equipConnectDirection == 1)
					{
						equipment3 = element;
					}
					else
					{
						equipment3 = element2;
					}
					double high3;
					if (this.getFloorOrCelingLevel(equipment3, InstallType.FC, out high3))
					{
						list2 = this.GetLinesAlongWall(nearestWall, element, nearestWall2, element2, installpos, high3);
					}
				}
				else if (equipConnectDirection == 1 && equipConnectDirection2 == 1)
				{
					if (nearestWall2.Equals(nearestWall))
					{
						list = this.GetSameWallLines(element, element2);
					}
					else
					{
						Connector deviceConnector = RevitUtils.GetDeviceConnector(element);
						Connector deviceConnector2 = RevitUtils.GetDeviceConnector(element2);
						double z;
						if (deviceConnector.Origin.Z > deviceConnector2.Origin.Z)
						{
							z = deviceConnector.Origin.Z;
						}
						else
						{
							z = deviceConnector2.Origin.Z;
						}
						list2 = this.GetLinesAlongWall(nearestWall, element, nearestWall2, element2, installpos, z);
					}
				}
			}
			if (list.Count > 0)
			{
				foreach (Curve curve in list)
				{
					list2.Add(new RouterLine
					{
						curve = curve,
						vecXyz = null
					});
				}
			}
			return list2;
		}

		private void CreateConduits(List<RouterLine> lines, WireStruct wire, WireParams wireParams, InstallType pos)
		{
			double conduitDiameter = wireParams.ConduitDiameter;
			for (int i = 0; i < lines.Count; i++)
			{
				Curve curve = lines[i].curve;
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				if (hyendPoint.DistanceTo(hyendPoint2) >= 0.005)
				{
					this.CreateConduitAndFitting(hyendPoint, hyendPoint2, wire, wireParams, pos, lines[i].vecXyz);
				}
			}
		}

		private void CreateConduitAndFitting(XYZ startPoint, XYZ endPoint, WireStruct wire, WireParams wireParams, InstallType pos, XYZ linevec)
		{
			ConduitType conduitType = this.m_doc.GetElementById(wireParams.ConduitTypeID) as ConduitType;
			double conduitDiameter = wireParams.ConduitDiameter;
			SubTransaction subTransaction = new SubTransaction(this.m_doc);
			subTransaction.Start();
			Conduit conduit = null;
			ConduitRouter conduit2 = null;
			if (this.usedConduits.Count > 0)
			{
				conduit = this.usedConduits[this.usedConduits.Count - 1].conduit;
				conduit2 = this.usedConduits[this.usedConduits.Count - 1];
			}
			if (conduit == null)
			{
				conduit = Conduit.Create(this.m_doc, conduitType.Id, startPoint, endPoint, this.m_doc.ActiveView.GenLevel.Id);
				conduit.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(conduitDiameter);
				this.SetConduitParameters(this.m_doc, conduit, wire.wireName(), true);
				ConduitRouter conduitRouter = new ConduitRouter();
				conduitRouter.conduit = conduit;
				conduitRouter.vec = linevec;
				this.usedConduits.Add(conduitRouter);
				this.m_oldConduits.Add(conduit);
				subTransaction.Commit();
				return;
			}
			Conduit conduit3 = Conduit.Create(this.m_doc, conduitType.Id, startPoint, endPoint, this.m_doc.ActiveView.GenLevel.Id);
			conduit3.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(conduitDiameter);
			this.SetConduitParameters(this.m_doc, conduit3, wire.wireName(), true);
			ConduitRouter conduitRouter2 = new ConduitRouter();
			conduitRouter2.conduit = conduit3;
			conduitRouter2.vec = linevec;
			this.usedConduits.Add(conduitRouter2);
			this.m_oldConduits.Add(conduit3);
			subTransaction.Commit();
			this.CreateFitting(conduit2, conduitRouter2, wireParams, pos, wire);
		}

		private void CreateFitting(ConduitRouter conduit1, ConduitRouter conduit2, WireParams wireParams, InstallType pos, WireStruct wire)
		{
			List<Connector> conduitConnectors = RevitUtils.GetConduitConnectors(conduit1.conduit);
			List<Connector> conduitConnectors2 = RevitUtils.GetConduitConnectors(conduit2.conduit);
			Connector connector = null;
			if (conduitConnectors2[1].Origin.IsAlmostEqualTo(conduitConnectors[0].Origin, CreateConduitFunction.approximate))
			{
				connector = conduitConnectors[0];
			}
			else if (conduitConnectors2[1].Origin.IsAlmostEqualTo(conduitConnectors[1].Origin, CreateConduitFunction.approximate))
			{
				connector = conduitConnectors[1];
			}
			else
			{
				connector = conduitConnectors2[0];
			}
			FamilyInstance familyInstance = null;
			foreach (FamilyInstance familyInstance2 in this.m_oldFittings)
			{
				XYZ point = (familyInstance2.Location as LocationPoint).Point;
				if (connector.Origin.IsAlmostEqualTo(point, CreateConduitFunction.approximate))
				{
					familyInstance = familyInstance2;
					break;
				}
			}
			XYZ xyz = null;
			if (connector.Origin.IsAlmostEqualTo(conduitConnectors[0].Origin, CreateConduitFunction.approximate))
			{
				xyz = conduitConnectors[1].Origin - conduitConnectors[0].Origin;
			}
			else
			{
				xyz = conduitConnectors[0].Origin - conduitConnectors[1].Origin;
			}
			xyz = xyz.Normalize();
			XYZ xyz2 = null;
			XYZ xyz3 = null;
			if (connector.Origin.IsAlmostEqualTo(conduitConnectors2[0].Origin, CreateConduitFunction.approximate))
			{
				xyz3 = conduitConnectors2[1].Origin - conduitConnectors2[0].Origin;
			}
			else
			{
				xyz3 = conduitConnectors2[0].Origin - conduitConnectors2[1].Origin;
			}
			xyz3 = xyz3.Normalize();
			this.mToFeet(wireParams.Level);
			double conduitDiameter = wireParams.ConduitDiameter;
			if (familyInstance == null)
			{
				FamilySymbol conduitFittings = this.GetConduitFittings(this.m_doc, "线管接线盒-四通");
				UnifiedModified.ActivateFamilySymbol(conduitFittings);
				familyInstance = this.m_doc.Create.NewFamilyInstance(connector.Origin, conduitFittings, 0);
				this.m_doc.Regenerate();
				if (xyz.IsAlmostEqualTo(XYZ.BasisZ) || xyz.IsAlmostEqualTo(-XYZ.BasisZ))
				{
					if (connector.Origin.IsAlmostEqualTo(conduitConnectors2[1].Origin, CreateConduitFunction.approximate))
					{
						xyz2 = conduitConnectors2[0].Origin;
					}
					else
					{
						xyz2 = conduitConnectors2[1].Origin;
					}
				}
				else if (connector.Origin.IsAlmostEqualTo(conduitConnectors[1].Origin, CreateConduitFunction.approximate))
				{
					xyz2 = conduitConnectors[0].Origin;
				}
				else
				{
					xyz2 = conduitConnectors[1].Origin;
				}
				familyInstance.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Set(connector.Origin.Z);
				XYZ xyz4 = -XYZ.BasisZ;
				if (pos == InstallType.CE)
				{
					bool flag = false;
					if (conduit1.vec != null && conduit1.vec.Normalize().IsAlmostEqualTo(XYZ.BasisZ))
					{
						flag = true;
					}
					if (conduit2.vec != null && conduit2.vec.Normalize().IsAlmostEqualTo(XYZ.BasisZ))
					{
						flag = true;
					}
					if (flag)
					{
						Line fittingRotateAxis = this.GetFittingRotateAxis(familyInstance);
						ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, fittingRotateAxis, Math.PI);
						xyz4 = XYZ.BasisZ;
					}
				}
				if (pos == InstallType.FC)
				{
					Line fittingRotateAxis2 = this.GetFittingRotateAxis(familyInstance);
					ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, fittingRotateAxis2, Math.PI);
					xyz4 = XYZ.BasisZ;
				}
				else if (pos == InstallType.WC || pos == InstallType.WS || pos == InstallType.SCE)
				{
					XYZ xyz5 = null;
					if (conduit1.vec != null)
					{
						xyz5 = conduit1.vec.Normalize();
					}
					else if (conduit2.vec != null)
					{
						xyz5 = conduit2.vec.Normalize();
					}
					if (xyz5 != null)
					{
						xyz4 = xyz5;
						Line fittingRotateAxis3 = this.GetFittingRotateAxis(familyInstance);
						ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, fittingRotateAxis3, Math.PI*.5);
						XYZ xyz6 = new XYZ(0.0, 1.0, 0.0);
						Connector connector2 = null;
						foreach (Connector connector3 in RevitUtils.GetConduitFittingConnectors(familyInstance))
						{
							XYZ basisZ = connector3.CoordinateSystem.BasisZ;
							if (basisZ.IsAlmostEqualTo(xyz6) || basisZ.IsAlmostEqualTo(-xyz6))
							{
								connector2 = connector3;
								break;
							}
						}
						double num = connector2.CoordinateSystem.BasisZ.Normalize().AngleOnPlaneTo(xyz5, XYZ.BasisZ);
						XYZ endPoint = connector.Origin + XYZ.BasisZ * 10.0;
						Line line = YJKLineEx.YJKGetBound(connector.Origin, endPoint);
						ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, line, num);
					}
				}
				XYZ vecConduit = xyz2 - connector.Origin;
				double rotateAngle = this.getRotateAngle(vecConduit, familyInstance, xyz4);
				XYZ endPoint2 = connector.Origin + xyz4 * 10.0;
				Line line2 = YJKLineEx.YJKGetBound(connector.Origin, endPoint2);
				ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, line2, -rotateAngle);
				this.SetFittingParameters(this.m_doc, familyInstance, wire.wireName(), true);
				this.m_oldFittings.Add(familyInstance);
			}
			this.m_doc.Regenerate();
			this.SetFittingParameters(this.m_doc, familyInstance, wire.wireName(), true);
			if (conduitDiameter < CreateConduitFunction.approximate)
			{
				TaskDialog.Show("提示", "线管直径为0");
			}
			this.connectConduitConnector(conduit1.conduit, xyz, familyInstance, conduitDiameter);
			this.connectConduitConnector(conduit2.conduit, xyz3, familyInstance, conduitDiameter);
		}

		private double getRotateAngle(XYZ vecConduit, FamilyInstance fitting, XYZ planNormal)
		{
			double num = double.MaxValue;
			if (vecConduit == null)
			{
				return 0.0;
			}
			vecConduit = vecConduit.Normalize();
			new List<Connector>();
			foreach (Connector connector in RevitUtils.GetConduitFittingConnectors(fitting))
			{
				if (!planNormal.IsAlmostEqualTo(connector.CoordinateSystem.BasisZ, CreateConduitFunction.approximate) && !(-planNormal).IsAlmostEqualTo(connector.CoordinateSystem.BasisZ, CreateConduitFunction.approximate))
				{
					double num2 = vecConduit.AngleOnPlaneTo(connector.CoordinateSystem.BasisZ, planNormal);
					if (num2 < num)
					{
						num = num2;
					}
				}
			}
			return num;
		}

		private void connectConduitConnector(Conduit conduit, XYZ vecConduit, FamilyInstance fitting, double diameter)
		{
			new List<Connector>();
			Connector connector = null;
			foreach (Connector connector2 in RevitUtils.GetConduitFittingConnectors(fitting))
			{
				if (vecConduit.Normalize().IsAlmostEqualTo(connector2.CoordinateSystem.BasisZ))
				{
					connector = connector2;
					break;
				}
			}
			if (connector == null)
			{
				return;
			}
			if (connector.AllRefs.Size < 1)
			{
				List<Connector> conduitConnectors = RevitUtils.GetConduitConnectors(conduit);
				double num = conduitConnectors[0].Origin.DistanceTo(connector.Origin);
				double num2 = conduitConnectors[1].Origin.DistanceTo(connector.Origin);
				connector.Radius = diameter / 2.0;
				XYZ xyz = null;
				XYZ xyz2 = null;
				Connector connector3 = null;
				Connector connector4 = null;
				if (num > num2)
				{
					xyz = conduitConnectors[0].Origin;
					xyz2 = connector.Origin;
					connector4 = conduitConnectors[0];
				}
				else
				{
					xyz2 = conduitConnectors[1].Origin;
					xyz = connector.Origin;
					connector4 = conduitConnectors[1];
				}
				ConnectorSet allRefs = connector4.AllRefs;
				if (allRefs.Size > 1)
				{
					foreach (object obj in allRefs)
					{
						Connector connector5 = (Connector)obj;
						if (connector5.Owner is FamilyInstance)
						{
							connector3 = connector5;
						}
					}
				}
				if (connector3 != null)
				{
					connector4.DisconnectFrom(connector3);
				}
				Line curve = Line.CreateBound(xyz, xyz2);
				(conduit.Location as LocationCurve).Curve = curve;
				List<Connector> conduitConnectors2 = RevitUtils.GetConduitConnectors(conduit);
				double num3 = conduitConnectors2[0].Origin.DistanceTo(connector.Origin);
				double num4 = conduitConnectors2[1].Origin.DistanceTo(connector.Origin);
				connector.Radius = diameter / 2.0;
				if (num3 > num4)
				{
					conduitConnectors2[1].ConnectTo(connector);
					if (connector3 != null)
					{
						conduitConnectors2[0].ConnectTo(connector3);
						return;
					}
				}
				else
				{
					conduitConnectors2[0].ConnectTo(connector);
					if (connector3 != null)
					{
						conduitConnectors2[1].ConnectTo(connector3);
					}
				}
			}
		}

		private Line GetFittingRotateAxis(FamilyInstance fitting)
		{
			Line result = null;
			XYZ xyz = new XYZ(1.0, 0.0, 0.0);
			List<Connector> list = new List<Connector>();
			foreach (Connector connector in RevitUtils.GetConduitFittingConnectors(fitting))
			{
				XYZ basisZ = connector.CoordinateSystem.BasisZ;
				if (basisZ.IsAlmostEqualTo(xyz) || basisZ.IsAlmostEqualTo(-xyz))
				{
					list.Add(connector);
				}
			}
			if (list.Count == 2)
			{
				result = Line.CreateBound(list[0].Origin, list[1].Origin);
			}
			return result;
		}

		private Connector GetFittingVerticalConnector(FamilyInstance fitting)
		{
			XYZ xyz = new XYZ(0.0, 0.0, 1.0);
			Connector result = null;
			foreach (Connector connector in RevitUtils.GetConduitFittingConnectors(fitting))
			{
				XYZ basisZ = connector.CoordinateSystem.BasisZ;
				if (basisZ.IsAlmostEqualTo(xyz) || basisZ.IsAlmostEqualTo(-xyz))
				{
					result = connector;
					break;
				}
			}
			return result;
		}

		public double mToFeet(double val)
		{
			return val * 1000.0 / 304.8;
		}

		public double mmToFeet(double val)
		{
			return val / 304.8;
		}

		private FamilySymbol GetConduitFittings(Document doc, string fittingName)
		{
			List<FamilySymbol> list = (from r in (from ele in RevitFilter.GetElementsOfType(doc, typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_ConduitFitting)
			select (FamilySymbol)ele).ToList<FamilySymbol>()
			where r.Family.Name == fittingName
			select r).ToList<FamilySymbol>();
			if (list.Count == 0)
			{
				if (!this.HYFittingFamily(doc, fittingName))
				{
					throw new Exception("加载配件族失败。");
				}
				list = (from r in (from ele in RevitFilter.GetElementsOfType(doc, typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_ConduitFitting)
				select (FamilySymbol)ele).ToList<FamilySymbol>()
				where r.Family.Name == fittingName
				select r).ToList<FamilySymbol>();
			}
			return list[0];
		}

		public bool HYFittingFamily(Document doc, string fittingName)
		{
			string text = Path.Combine(Product.FamilyLocation, RevitVersion.GetVersionNumber(doc), "ConduitFitting", fittingName + ".rfa");
			return doc.LoadFamily(text);
		}

		private void SetConduitParameters(Document doc, Conduit conduit, string wireid, bool isAdd = true)
		{
			Dictionary<string, ParameterType> dictionary = new Dictionary<string, ParameterType>();
            dictionary.Add("所含导线", (ParameterType)1);
			foreach (KeyValuePair<string, ParameterType> keyValuePair in dictionary)
			{
				if (conduit.GetParameter(keyValuePair.Key) == null)
				{
					YArchitech.Revit.Electric.Common.SharedParameter.InsertSharedParameter(doc, BuiltInCategory.OST_Conduit, "电气数据", dictionary, true);
					break;
				}
			}
			if (isAdd)
			{
				string text = conduit.GetParameter("所含导线").AsString();
				text = this.MergeExtWireId(text, wireid);
				conduit.GetParameter("所含导线").Set(text);
				return;
			}
			conduit.GetParameter("所含导线").Set(wireid);
		}

		private void SetFittingParameters(Document doc, FamilyInstance fitting, string wireid, bool isAdd = true)
		{
			Dictionary<string, ParameterType> dictionary = new Dictionary<string, ParameterType>();
            dictionary.Add("所含导线", (ParameterType)1);
			foreach (KeyValuePair<string, ParameterType> keyValuePair in dictionary)
			{
				if (fitting.GetParameter(keyValuePair.Key) == null)
				{
					YArchitech.Revit.Electric.Common.SharedParameter.InsertSharedParameter(doc, BuiltInCategory.OST_ConduitFitting, "电气数据", dictionary, true);
					break;
				}
			}
			if (isAdd)
			{
				string text = fitting.GetParameter("所含导线").AsString();
				text = this.MergeExtWireId(text, wireid);
				fitting.GetParameter("所含导线").Set(text);
				return;
			}
			fitting.GetParameter("所含导线").Set(wireid);
		}

		private bool GetWireProperties(Document doc, Wire wire, ref WireParams conduitParams)
		{
			try
			{
				if (string.IsNullOrEmpty(wire.GetParameter("线管类型ID").AsString()))
				{
					string conduitTypeName = wire.GetParameter("线管类型").AsString();
					conduitParams.ConduitTypeID = this.GetConduitTypeIdByName(doc, conduitTypeName);
				}
				else
				{
					conduitParams.ConduitTypeID = new ElementId(Convert.ToInt32(wire.GetParameter("线管类型ID").AsString()));
				}
				conduitParams.ConduitDiameter = wire.GetParameter("管径").AsDouble();
				Level genLevel = doc.ActiveView.GenLevel;
				conduitParams.Level = genLevel.Elevation * 304.8 / 1000.0 + wire.GetParameter("相对标高").AsDouble();
				conduitParams.LayMode = wire.GetParameter("敷设方式").AsString();
			}
			catch (Exception)
			{
				return false;
			}
			return !(conduitParams.ConduitTypeID == null) && conduitParams.ConduitDiameter != 0.0;
		}

		private ElementId GetConduitTypeIdByName(Document doc, string conduitTypeName)
		{
			ElementId result = null;
			IList<Element> source = RevitFilter.GetElementsOfType(doc, typeof(ConduitType)).ToElements();
			IEnumerable<Element> source2 = from ctt in source
			where ctt.Name == conduitTypeName && (ctt as ConduitType).GetParameter(BuiltInParameter.ALL_MODEL_FAMILY_NAME).AsString() == "带配件的线管"
			select ctt;
			if (source2.Count<Element>() > 0)
			{
				result = source2.First<Element>().Id;
			}
			else
			{
				source2 = from ctt in source
				where ctt.Name == conduitTypeName
				select ctt;
				if (source2.Count<Element>() > 0)
				{
					result = source2.First<Element>().Id;
				}
			}
			return result;
		}

		private List<Wire> GetElementWire(Element element)
		{
			List<Wire> list = new List<Wire>();
			ConnectorSet allRefs = RevitUtils.GetDeviceConnector(element).AllRefs;
			if (allRefs.Size <= 0)
			{
				return list;
			}
			foreach (object obj in allRefs)
			{
				Element owner = ((Connector)obj).Owner;
				if (owner is Wire && !list.Contains(owner, CreateConduitFunction.elementIDCompare))
				{
					list.Add(owner as Wire);
				}
			}
			return list;
		}

		private RoomData GetEquipmentRoom(Wall wall, Element element, List<RoomData> roomDataList)
		{
			XYZ origin = RevitUtils.GetDeviceConnector(element).Origin;
			RoomData result = null;
			double num = double.MaxValue;
			ElementId id = wall.Id;
			foreach (RoomData roomData in roomDataList)
			{
				foreach (RoomData.BoundingSegment boundingSegment in roomData.WallSegmentList)
				{
					if (boundingSegment.WallId.Equals(id))
					{
						double num2 = boundingSegment.Curve.Distance(origin);
						if (num2 < num)
						{
							result = roomData;
							num = num2;
							break;
						}
						break;
					}
				}
			}
			return result;
		}

		private List<RouterLine> GetLinesAlongWall(Wall wallStart, Element startElement, Wall wallEnd, Element endElement, InstallType installpos, double high)
		{
			List<Curve> list = new List<Curve>();
			List<RouterLine> list2 = new List<RouterLine>();
			if (this.m_roomList.Count < 1)
			{
				string text = string.Format("当前视图或链接文件中没有可以构成的房间！ ", Array.Empty<object>());
				TaskDialog.Show("提示", text);
				return list2;
			}
			RoomData equipmentRoom = this.GetEquipmentRoom(wallStart, startElement, this.m_roomList);
			RoomData equipmentRoom2 = this.GetEquipmentRoom(wallEnd, endElement, this.m_roomList);
			List<RoomData.BoundingSegment> segments = new List<RoomData.BoundingSegment>();
			if (equipmentRoom.RoomId.Equals(equipmentRoom2.RoomId))
			{
				list = this.getRoomLines(wallStart, startElement, wallEnd, endElement, equipmentRoom, installpos, out segments);
			}
			else
			{
				bool flag = false;
				bool flag2 = false;
				foreach (RoomData.BoundingSegment boundingSegment in equipmentRoom.WallSegmentList)
				{
					if (boundingSegment.WallId.Equals(wallStart.Id))
					{
						flag = true;
					}
					if (boundingSegment.WallId.Equals(wallEnd.Id))
					{
						flag2 = true;
					}
				}
				if (flag && flag2)
				{
					list = this.getRoomLines(wallStart, startElement, wallEnd, endElement, equipmentRoom, installpos, out segments);
				}
				else
				{
					list = this.getRoomLines(wallStart, startElement, wallEnd, endElement, equipmentRoom2, installpos, out segments);
				}
			}
			Connector deviceConnector = RevitUtils.GetDeviceConnector(startElement);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(endElement);
			for (int i = 0; i < list.Count; i++)
			{
				Curve curve = list[i];
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				XYZ xyz2;
				if (i == 0 && !high.Equals(deviceConnector.Origin.Z))
				{
					XYZ xyz = new XYZ(hyendPoint.X, hyendPoint.Y, deviceConnector.Origin.Z);
					xyz2 = new XYZ(hyendPoint.X, hyendPoint.Y, high);
					Line curve2 = Line.CreateBound(xyz, xyz2);
					list2.Add(new RouterLine
					{
						curve = curve2,
						vecXyz = this.GetWallVec(curve2, segments)
					});
				}
				XYZ xyz3 = new XYZ(hyendPoint.X, hyendPoint.Y, high);
				xyz2 = new XYZ(hyendPoint2.X, hyendPoint2.Y, high);
				Line curve3 = Line.CreateBound(xyz3, xyz2);
				list2.Add(new RouterLine
				{
					curve = curve3,
					vecXyz = this.GetWallVec(curve3, segments)
				});
				if (list.Count - 1 == i && !high.Equals(deviceConnector2.Origin.Z))
				{
					XYZ xyz4 = new XYZ(hyendPoint2.X, hyendPoint2.Y, high);
					xyz2 = new XYZ(hyendPoint2.X, hyendPoint2.Y, deviceConnector2.Origin.Z);
					Line curve4 = Line.CreateBound(xyz4, xyz2);
					list2.Add(new RouterLine
					{
						curve = curve4,
						vecXyz = this.GetWallVec(curve4, segments)
					});
				}
			}
			return list2;
		}

		private List<Curve> getRoomLines(Wall wallStart, Element startElement, Wall wallEnd, Element endElement, RoomData room, InstallType installpos, out List<RoomData.BoundingSegment> segments)
		{
			List<Curve> list = new List<Curve>();
			List<XYZ> list2 = new List<XYZ>();
			segments = this.GetOffsetBoundingSegment(wallStart, startElement, wallEnd, endElement, room, installpos);
			if (segments.Count < 1)
			{
				return list;
			}
			list2 = this.getMinimumLenghtsPoints(wallStart, startElement, wallEnd, endElement, segments);
			int equipConnectDirection = this.GetEquipConnectDirection(startElement);
			int equipConnectDirection2 = this.GetEquipConnectDirection(endElement);
			Connector deviceConnector = RevitUtils.GetDeviceConnector(startElement);
			XYZ xyz = new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, 0.0);
			if (!xyz.IsAlmostEqualTo(list2[0], CreateConduitFunction.approximate) && equipConnectDirection != 1)
			{
				list2.Insert(0, xyz);
			}
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(endElement);
			XYZ xyz2 = new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, 0.0);
			if (!xyz2.IsAlmostEqualTo(list2[list2.Count - 1], CreateConduitFunction.approximate) && equipConnectDirection2 != 1)
			{
				list2.Add(xyz2);
			}
			new List<RouterLine>();
			for (int i = 0; i < list2.Count - 1; i++)
			{
				XYZ xyz3 = list2[i];
				XYZ xyz4 = list2[i + 1];
				Line item = Line.CreateBound(xyz3, xyz4);
				list.Add(item);
			}
			return list;
		}

		private XYZ GetWallVec(Curve curve, List<RoomData.BoundingSegment> segments)
		{
			XYZ xyz = null;
			XYZ xyz2 = new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, 0.0);
			XYZ xyz3 = new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, 0.0);
			foreach (RoomData.BoundingSegment boundingSegment in segments)
			{
				Curve curve2 = boundingSegment.Curve;
				if (curve2.Distance(xyz2) < CreateConduitFunction.approximate && curve2.Distance(xyz3) < CreateConduitFunction.approximate)
				{
					xyz = curve2.GetEndPoint(1) - curve2.GetEndPoint(0);
					xyz = -xyz.CrossProduct(XYZ.BasisZ);
					break;
				}
			}
			if (xyz != null)
			{
				xyz = xyz.Normalize();
			}
			return xyz;
		}

		private List<RoomData.BoundingSegment> GetOffsetBoundingSegment(Wall wallStart, Element startElement, Wall wallEnd, Element endElement, RoomData room, InstallType installpos)
		{
			Connector deviceConnector = RevitUtils.GetDeviceConnector(startElement);
			new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, 0.0);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(endElement);
			new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, 0.0);
			List<Curve> list = new List<Curve>();
			foreach (RoomData.BoundingSegment boundingSegment in room.WallSegmentList)
			{
				list.Add(boundingSegment.Curve);
			}
			double num;
			if (installpos == InstallType.WC || installpos == InstallType.SCE)
			{
				num = this.m_dThick / 2.0;
			}
			else
			{
				if (installpos != InstallType.WS)
				{
					return room.WallSegmentList;
				}
				num = -this.m_dThick / 2.0;
			}
			List<List<Curve>> list2 = new StructureLoopSearcher(this.m_doc).OffsetLoop(list, num);
			if (list2.Count == 1 && list2[0].Count == room.WallSegmentList.Count)
			{
				List<RoomData.BoundingSegment> list3 = new List<RoomData.BoundingSegment>();
				foreach (Curve curve in list2[0])
				{
					for (int i = 0; i < room.WallSegmentList.Count; i++)
					{
						Curve curve2 = room.WallSegmentList[i].Curve;
						XYZ xyz = (curve2.GetEndPoint(0) + curve2.GetEndPoint(1)) / 2.0;
						xyz = new XYZ(xyz.X, xyz.Y, 0.0);
						double num2 = curve.Distance(xyz);
						if (Math.Abs(Math.Abs(num) - num2) < CreateConduitFunction.approximate)
						{
							RoomData.BoundingSegment item = new RoomData.BoundingSegment(curve, room.WallSegmentList[i].WallId);
							list3.Add(item);
							break;
						}
					}
				}
				return list3;
			}
			return room.WallSegmentList;
		}

		private List<XYZ> getMinimumLenghtsPoints(Wall wallStart, Element startElement, Wall wallEnd, Element endElement, List<RoomData.BoundingSegment> WallSegmentList)
		{
			Connector deviceConnector = RevitUtils.GetDeviceConnector(startElement);
			XYZ pt = new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, 0.0);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(endElement);
			XYZ pt2 = new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, 0.0);
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			XYZ pt3 = null;
			XYZ pt4 = null;
			XYZ wallendpts = null;
			XYZ wallendpte = null;
			XYZ closePt = null;
			List<XYZ> list3 = new List<XYZ>();
			List<RoomData.BoundingSegment> list4 = new List<RoomData.BoundingSegment>(WallSegmentList.ToArray());
			if (wallStart.Id.Equals(wallEnd.Id))
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				for (int i = 0; i < list4.Count; i++)
				{
					RoomData.BoundingSegment boundingSegment = list4[i];
					if (boundingSegment.WallId.Equals(wallStart.Id))
					{
						xyz = this.getCloserPoint(pt, boundingSegment.Curve);
						xyz2 = this.getCloserPoint(pt2, boundingSegment.Curve);
						break;
					}
				}
				if (xyz.IsAlmostEqualTo(xyz2, CreateConduitFunction.approximate))
				{
					list3.Add(xyz);
				}
				else
				{
					list3.Add(xyz);
					list3.Add(xyz2);
				}
			}
			else
			{
				ElementId id = wallStart.Id;
				ElementId id2 = wallEnd.Id;
				for (int j = 0; j < list4.Count; j++)
				{
					RoomData.BoundingSegment boundingSegment2 = list4[j];
					if (boundingSegment2.WallId.Equals(id))
					{
						XYZ closerPoint = this.getCloserPoint(pt, boundingSegment2.Curve);
						XYZ hyendPoint = boundingSegment2.Curve.GetEndPoint(0);
						XYZ hyendPoint2 = boundingSegment2.Curve.GetEndPoint(1);
						if (!closerPoint.IsAlmostEqualTo(hyendPoint, CreateConduitFunction.approximate) && !closerPoint.IsAlmostEqualTo(hyendPoint2, CreateConduitFunction.approximate))
						{
							list.Add(closerPoint);
							list.Add(hyendPoint);
							pt3 = hyendPoint;
							list2.Add(closerPoint);
							list2.Add(hyendPoint2);
							pt4 = hyendPoint2;
						}
						else if (closerPoint.IsAlmostEqualTo(hyendPoint, CreateConduitFunction.approximate))
						{
							list.Add(hyendPoint);
							pt3 = hyendPoint;
							list2.Add(closerPoint);
							list2.Add(hyendPoint2);
							pt4 = hyendPoint2;
						}
						else if (closerPoint.IsAlmostEqualTo(hyendPoint2, CreateConduitFunction.approximate))
						{
							list.Add(closerPoint);
							list.Add(hyendPoint);
							pt3 = hyendPoint;
							list2.Add(hyendPoint2);
							pt4 = hyendPoint2;
						}
						list4.RemoveAt(j);
						j--;
					}
					if (boundingSegment2.WallId.Equals(id2))
					{
						closePt = this.getCloserPoint(pt2, boundingSegment2.Curve);
						wallendpts = boundingSegment2.Curve.GetEndPoint(0);
						wallendpte = boundingSegment2.Curve.GetEndPoint(1);
					}
				}
				this.getOneSidePoint(pt3, list4, wallendpts, wallendpte, closePt, endElement, ref list);
				this.getOneSidePoint(pt4, list4, wallendpts, wallendpte, closePt, endElement, ref list2);
				double num = this.CalculateLenght(list);
				double num2 = this.CalculateLenght(list2);
				if (num < num2)
				{
					list3 = list;
				}
				else
				{
					list3 = list2;
				}
			}
			return list3;
		}

		private double CalculateLenght(List<XYZ> listPts)
		{
			double num = 0.0;
			for (int i = 0; i < listPts.Count - 1; i++)
			{
				num += listPts[i].DistanceTo(listPts[i + 1]);
			}
			return num;
		}

		private void getOneSidePoint(XYZ pt, List<RoomData.BoundingSegment> seglist, XYZ wallendpts, XYZ wallendpte, XYZ closePt, Element endElement, ref List<XYZ> listPts)
		{
			int i = 0;
			while (i < seglist.Count)
			{
				RoomData.BoundingSegment boundingSegment = seglist[i];
				XYZ hyendPoint = boundingSegment.Curve.GetEndPoint(0);
				XYZ hyendPoint2 = boundingSegment.Curve.GetEndPoint(1);
				if (pt.IsAlmostEqualTo(wallendpts, CreateConduitFunction.approximate))
				{
					if (!wallendpts.IsAlmostEqualTo(closePt))
					{
						listPts.Add(closePt);
						return;
					}
					break;
				}
				else if (pt.IsAlmostEqualTo(wallendpte, CreateConduitFunction.approximate))
				{
					if (!wallendpte.IsAlmostEqualTo(closePt))
					{
						listPts.Add(closePt);
						return;
					}
					break;
				}
				else
				{
					bool flag = false;
					if (pt.IsAlmostEqualTo(hyendPoint, CreateConduitFunction.approximate))
					{
						listPts.Add(hyendPoint2);
						pt = hyendPoint2;
						flag = true;
					}
					else if (pt.IsAlmostEqualTo(hyendPoint2, CreateConduitFunction.approximate))
					{
						listPts.Add(hyendPoint);
						pt = hyendPoint;
						flag = true;
					}
					if (flag)
					{
						seglist.RemoveAt(i);
						i--;
						this.getOneSidePoint(pt, seglist, wallendpts, wallendpte, closePt, endElement, ref listPts);
						return;
					}
					i++;
				}
			}
		}

		private XYZ getCloserPoint(XYZ pt, Curve curve)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = hyendPoint2 - hyendPoint;
			Line.CreateUnbound(pt, xyz.CrossProduct(XYZ.BasisZ));
			IntersectionResult intersectionResult = curve.Project(pt);
			XYZ result;
			if (intersectionResult == null)
			{
				if (pt.DistanceTo(hyendPoint) < pt.DistanceTo(hyendPoint2))
				{
					result = hyendPoint;
				}
				else
				{
					result = hyendPoint2;
				}
			}
			else
			{
				result = intersectionResult.XYZPoint;
			}
			return result;
		}

		private List<Curve> GetSameWallLines(Element startElement, Element endElement)
		{
			List<Curve> list = new List<Curve>();
			Connector deviceConnector = RevitUtils.GetDeviceConnector(startElement);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(endElement);
			XYZ basisZ = deviceConnector.CoordinateSystem.BasisZ;
			double num = this.m_dThick / 2.0;
			if (Math.Abs(deviceConnector.Origin.Z - deviceConnector2.Origin.Z) < CreateConduitFunction.approximate)
			{
				XYZ xyz = deviceConnector.Origin + basisZ * num;
				XYZ xyz2 = deviceConnector2.Origin + basisZ * num;
				Line item = Line.CreateBound(xyz, xyz2);
				list.Add(item);
			}
			else
			{
				XYZ xyz3;
				if (deviceConnector.Origin.Z < deviceConnector2.Origin.Z)
				{
					xyz3 = new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, deviceConnector2.Origin.Z);
				}
				else
				{
					xyz3 = new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, deviceConnector.Origin.Z);
				}
                //deviceConnector.Origin + basisZ * num;
                //xyz3 + basisZ * num;
				Line item2 = Line.CreateBound(deviceConnector.Origin, xyz3);
				list.Add(item2);
                //deviceConnector2.Origin + basisZ * num;
				Line item3 = Line.CreateBound(xyz3, deviceConnector2.Origin);
				list.Add(item3);
			}
			return list;
		}

		private List<Curve> GetCcAndCeTypeLines(WireStruct wire, InstallType installpos)
		{
			Element element = wire.startElement();
			Element element2 = wire.endElement();
			Connector deviceConnector = RevitUtils.GetDeviceConnector(element);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(element2);
			List<Curve> list = new List<Curve>();
			double num;
			bool floorOrCelingLevel = this.getFloorOrCelingLevel(element, installpos, out num);
			double num2;
			bool floorOrCelingLevel2 = this.getFloorOrCelingLevel(element2, installpos, out num2);
			double num3 = Math.Abs(deviceConnector.Origin.Z - num);
			double num4 = Math.Abs(deviceConnector2.Origin.Z - num2);
			if (num3 < this.m_dThick || num4 < this.m_dThick)
			{
				double num5;
				if (num3 > num4)
				{
					num5 = num4;
				}
				else
				{
					num5 = num3;
				}
				num5 += this.m_dThick;
				if (InstallType.FC == installpos)
				{
					num -= num5;
					num2 -= num5;
				}
				else
				{
					num += num5;
					num2 += num5;
				}
				this.m_isImproveDefultHigh = true;
			}
			double num6 = 0.0;
			double num7 = 0.0;
			bool flag = false;
			if (floorOrCelingLevel && floorOrCelingLevel2 && !num.Equals(num2))
			{
				num6 = num;
				num7 = num2;
				flag = true;
			}
			else if (floorOrCelingLevel && floorOrCelingLevel2 && num.Equals(num2))
			{
				num6 = num;
				num7 = num;
				flag = true;
			}
			else if (floorOrCelingLevel && !floorOrCelingLevel2)
			{
				num6 = num;
				num7 = num;
				flag = true;
			}
			else if (!floorOrCelingLevel && floorOrCelingLevel2)
			{
				num6 = num2;
				num7 = num2;
				flag = true;
			}
			if (flag)
			{
				XYZ xyz = new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, num6);
				XYZ xyz2 = new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, num7);
				Line item = Line.CreateBound(deviceConnector.Origin, xyz);
				list.Add(item);
				string versionNumber = this.m_doc.Application.VersionNumber;
				if (versionNumber.CompareTo("2016") != 0 && versionNumber.CompareTo("2017") != 0 && versionNumber.CompareTo("2018") != 0)
				{
					List<XYZ> list2 = wire.wirePoints();
					if (!deviceConnector.Origin.IsAlmostEqualTo(list2[0], CreateConduitFunction.approximate))
					{
						list2.Reverse();
					}
					for (int i = 0; i < list2.Count - 1; i++)
					{
						XYZ xyz3 = new XYZ(list2[i].X, list2[i].Y, num6);
						XYZ xyz4 = new XYZ(list2[i + 1].X, list2[i + 1].Y, num6);
						Line item2 = Line.CreateBound(xyz3, xyz4);
						list.Add(item2);
					}
				}
				else
				{
					Line item3 = Line.CreateBound(xyz, xyz2);
					list.Add(item3);
				}
				Line item4 = Line.CreateBound(xyz2, deviceConnector2.Origin);
				list.Add(item4);
			}
			else
			{
				TaskDialog.Show("提示", "没有找到相应的楼板！");
			}
			return list;
		}

		private bool getFloorLevel(XYZ pt, InstallType installpos, out double dTopHigh)
		{
			bool flag = false;
			dTopHigh = double.MinValue;
			if (this.m_FloorList.Count < 1)
			{
				return flag;
			}
			XYZ xyz = XYZ.BasisZ;
			if (InstallType.FC == installpos)
			{
				xyz = -xyz;
			}
			Line line = Line.CreateUnbound(pt, xyz);
			double num;
			if (InstallType.FC != installpos)
			{
				num = double.MaxValue;
			}
			else
			{
				num = double.MinValue;
			}
			double num2 = 0.0;
			double num3 = 0.0;
			XYZ xyz2 = new XYZ();
			for (int i = 0; i < this.m_FloorList.Count; i++)
			{
				Element elem = this.m_FloorList[i];
				Options options = new Options();
				options.ComputeReferences = true;
				foreach (GeometryObject geometryObject in new YJKElement(elem).GetGeometry(options))
				{
					if (geometryObject is Solid)
					{
						bool flag2 = false;
						Solid solid = geometryObject as Solid;
						if (!(null == solid))
						{
							FaceArray faces = solid.Faces;
							double num4 = 0.0;
							double num5 = 0.0;
							foreach (object obj in faces)
							{
								PlanarFace planarFace = obj as PlanarFace;
								if (!(null == planarFace))
								{
									if (planarFace.FaceNormal().Z > 0.0)
									{
										num4 = planarFace.Origin.Z;
									}
									else if (planarFace.FaceNormal().Z < 0.0)
									{
										num5 = planarFace.Origin.Z;
									}
									IntersectionResultArray intersectionResultArray;
                                    if ((planarFace.FaceNormal().Z < 0.0 || planarFace.FaceNormal().Z > 0.0) && planarFace.Intersect(line, out intersectionResultArray) != (SetComparisonResult)4)
									{
										xyz2 = intersectionResultArray.get_Item(0).XYZPoint;
										if (InstallType.FC != installpos)
										{
											if (xyz2.Z < pt.Z)
											{
												break;
											}
											if (xyz2.Z > num)
											{
												break;
											}
										}
										else
										{
											if (xyz2.Z > pt.Z)
											{
												break;
											}
											if (xyz2.Z < num)
											{
												break;
											}
										}
										num = xyz2.Z;
										flag2 = true;
										flag = true;
									}
								}
							}
							if (flag2)
							{
								num2 = num4;
								num3 = num5;
							}
						}
					}
				}
			}
			if (flag)
			{
				if (installpos == InstallType.CC || installpos == InstallType.WC)
				{
					dTopHigh = num + (num2 - num3) / 3.0;
				}
				if (InstallType.CE == installpos)
				{
					dTopHigh = num - this.m_dThick / 2.0;
				}
				if (InstallType.SCE == installpos)
				{
					dTopHigh = num - this.mmToFeet((double)this.m_BotFloorDis);
				}
				if (InstallType.FC == installpos)
				{
					dTopHigh = num - this.mmToFeet((double)this.m_HighGroundDis);
				}
			}
			return flag;
		}

		private bool getCelingLevel(XYZ pt, out double dTopHigh)
		{
			dTopHigh = double.MinValue;
			bool result = false;
			double num = double.MaxValue;
			foreach (Element elem in this.m_CeilingList)
			{
				Options options = new Options();
				options.ComputeReferences = true;
				foreach (GeometryObject geometryObject in new YJKElement(elem).GetGeometry(options))
				{
					if (geometryObject is Solid)
					{
						foreach (object obj in (geometryObject as Solid).Faces)
						{
							PlanarFace planarFace = obj as PlanarFace;
							if (planarFace.FaceNormal().Z < 0.0)
							{
								Line line = Line.CreateUnbound(pt, XYZ.BasisZ);
								IntersectionResultArray intersectionResultArray;
								planarFace.Intersect(line, out intersectionResultArray);
								if (intersectionResultArray.Size == 1)
								{
									XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
									dTopHigh = xyzpoint.Z;
									if (dTopHigh < pt.Z)
									{
										break;
									}
									if (dTopHigh < num)
									{
										num = dTopHigh;
									}
									else
									{
										dTopHigh = num;
									}
									result = true;
									return result;
								}
							}
						}
					}
				}
			}
			return result;
		}

		private bool getFloorOrCelingLevel(Element equipment, InstallType installpos, out double dTopHigh)
		{
			dTopHigh = double.MinValue;
			XYZ origin = RevitUtils.GetDeviceConnector(equipment).Origin;
			if (InstallType.CE == installpos)
			{
				bool celingLevel = this.getCelingLevel(origin, out dTopHigh);
				if (celingLevel)
				{
					dTopHigh -= this.m_dThick / 2.0;
					return celingLevel;
				}
			}
			if (InstallType.SCE == installpos)
			{
				bool celingLevel = this.getCelingLevel(origin, out dTopHigh);
				if (celingLevel)
				{
					dTopHigh += this.mmToFeet((double)this.m_TopCelingDis);
					return celingLevel;
				}
			}
			return this.getFloorLevel(origin, installpos, out dTopHigh);
		}

		private XYZ GetNearestPoint(Wall wall, XYZ pt)
		{
			Curve curve = (wall.Location as LocationCurve).Curve;
			XYZ xyz = curve.GetEndPoint(1) - curve.GetEndPoint(0);
			xyz = xyz.CrossProduct(XYZ.BasisZ);
			Line line = Line.CreateUnbound(pt, xyz);
			IntersectionResultArray intersectionResultArray;
			int num = (int)curve.Intersect(line, out intersectionResultArray);
			new XYZ();
			if (num == 4)
			{
				double num2 = pt.DistanceTo(curve.GetEndPoint(0));
				double num3 = pt.DistanceTo(curve.GetEndPoint(1));
				if (num2 >= num3)
				{
					curve.GetEndPoint(1);
				}
				else
				{
					curve.GetEndPoint(0);
				}
			}
			return intersectionResultArray.get_Item(0).XYZPoint;
		}

		private int GetEquipConnectDirection(Element equipElement)
		{
			Parameter parameter = equipElement.GetParameter("安装方式");
			if (parameter != null)
			{
				string text = parameter.AsString();
				if (text != "" && text != null)
				{
					int equipConnectDirectionByString = this.GetEquipConnectDirectionByString(text);
					if (-1 != equipConnectDirectionByString)
					{
						return equipConnectDirectionByString;
					}
				}
			}
			ConnectorSet connectors = (equipElement as FamilyInstance).MEPModel.ConnectorManager.Connectors;
			if (connectors.Size != 1)
			{
				return -1;
			}
			XYZ xyz = new XYZ();
			foreach (object obj in connectors)
			{
				xyz = ((Connector)obj).CoordinateSystem.BasisZ;
			}
			if (xyz.Z == 1.0)
			{
				return 0;
			}
			if (xyz.Z == -1.0)
			{
				return 2;
			}
			return 1;
		}

		private int GetEquipConnectDirectionByString(string direction)
		{
			string b = null;
			foreach (RelationData relationData in this.m_RelationDataList)
			{
				if (direction.Equals(relationData.strKey))
				{
					b = relationData.strDirection;
					break;
				}
			}
			int result;
			if ("上" == b)
			{
				result = 0;
			}
			else if ("中" == b)
			{
				result = 1;
			}
			else if ("下" == b)
			{
				result = 2;
			}
			else
			{
                result = -1;
			}
			return result;
		}

		private void getALLDocWaLLs()
		{
			this.m_wallList.Clear();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id);
			filteredElementCollector.WherePasses(new ElementClassFilter(typeof(Wall)));
			foreach (Element element in filteredElementCollector.ToElements())
			{
				if (element != null)
				{
					Wall item = element as Wall;
					this.m_wallList.Add(item);
				}
			}
			double elevation = this.m_doc.ActiveView.GenLevel.Elevation;
			foreach (Document document in this.m_allLinkDocs)
			{
				if (document != null)
				{
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(document);
					filteredElementCollector2.WherePasses(new ElementClassFilter(typeof(Wall)));
					foreach (Element element2 in filteredElementCollector2.ToElements())
					{
						if (element2 != null)
						{
							Wall wall = element2 as Wall;
							if (Math.Abs((document.GetElementById(wall.LevelId) as Level).Elevation - elevation) < CreateConduitFunction.approximate)
							{
								this.m_wallList.Add(wall);
							}
						}
					}
				}
			}
		}

		private void getALLDocCelings()
		{
			this.m_CeilingList.Clear();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementClassFilter(typeof(Ceiling)));
			foreach (Element element in filteredElementCollector.ToElements())
			{
				if (element != null)
				{
					Ceiling item = element as Ceiling;
					this.m_CeilingList.Add(item);
				}
			}
			double elevation = this.m_doc.ActiveView.GenLevel.Elevation;
			foreach (Document document in this.m_allLinkDocs)
			{
				if (document != null)
				{
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(document);
					filteredElementCollector2.WherePasses(new ElementClassFilter(typeof(Ceiling)));
					foreach (Element element2 in filteredElementCollector2.ToElements())
					{
						if (element2 != null)
						{
							Ceiling item2 = element2 as Ceiling;
							this.m_CeilingList.Add(item2);
						}
					}
				}
			}
		}

		private void getALLDocFloor()
		{
			this.m_FloorList.Clear();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementClassFilter(typeof(Floor)));
			foreach (Element element in filteredElementCollector.ToElements())
			{
				if (element != null)
				{
					Floor item = element as Floor;
					this.m_FloorList.Add(item);
				}
			}
			double elevation = this.m_doc.ActiveView.GenLevel.Elevation;
			foreach (Document document in this.m_allLinkDocs)
			{
				if (document != null)
				{
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(document);
					filteredElementCollector2.WherePasses(new ElementClassFilter(typeof(Floor)));
					foreach (Element element2 in filteredElementCollector2.ToElements())
					{
						if (element2 != null)
						{
							Floor item2 = element2 as Floor;
							this.m_FloorList.Add(item2);
						}
					}
				}
			}
		}

		private void getALLDocStructuralFramings()
		{
			this.m_GirderList.Clear();
			foreach (Element element in RevitFilter.GetElementByCategory(this.m_doc, BuiltInCategory.OST_StructuralFraming).ToList<Element>())
			{
				if (element != null)
				{
					FamilyInstance familyInstance = element as FamilyInstance;
					if (familyInstance != null)
					{
						this.m_GirderList.Add(familyInstance);
					}
				}
			}
			foreach (Document document in this.m_allLinkDocs)
			{
				if (document != null)
				{
					foreach (Element element2 in RevitFilter.GetElementByCategory(document, BuiltInCategory.OST_StructuralFraming).ToList<Element>())
					{
						if (element2 != null)
						{
							FamilyInstance familyInstance2 = element2 as FamilyInstance;
							if (familyInstance2 != null)
							{
								this.m_GirderList.Add(familyInstance2);
							}
						}
					}
				}
			}
		}

		private Wall GetNearestWall(Element element, out double distance)
		{
			distance = double.MaxValue;
			XYZ origin = RevitUtils.GetDeviceConnector(element).Origin;
			int index = 0;
			for (int i = 0; i < this.m_wallList.Count; i++)
			{
				double num = (this.m_wallList[i].Location as LocationCurve).Curve.Distance(origin);
				if (num < distance)
				{
					distance = num;
					index = i;
				}
			}
			return this.m_wallList[index];
		}

		private bool GetRoomDataInfos(ref List<RoomData> roomDataList)
		{
			List<Room> list = new List<Room>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementClassFilter(typeof(SpatialElement)));
			IEnumerable<Element> enumerable = filteredElementCollector.ToElements();
			double elevation = this.m_doc.ActiveView.GenLevel.Elevation;
			foreach (Element element in enumerable)
			{
				if (element != null)
				{
					Room room = element as Room;
					if (room != null && !(ElementId.InvalidElementId == room.LevelId) && Math.Abs((this.m_doc.GetElementById(room.LevelId) as Level).Elevation - elevation) < CreateConduitFunction.approximate)
					{
						list.Add(room);
					}
				}
			}
			foreach (Document document in this.m_allLinkDocs)
			{
				if (document != null)
				{
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(document);
					filteredElementCollector2.WherePasses(new ElementClassFilter(typeof(SpatialElement)));
					IEnumerable<Element> enumerable2 = filteredElementCollector2.ToElements();
					double elevation2 = this.m_doc.ActiveView.GenLevel.Elevation;
					foreach (Element element2 in enumerable2)
					{
						if (element2 != null)
						{
							Room room2 = element2 as Room;
							if (room2 != null && !(ElementId.InvalidElementId == room2.LevelId) && Math.Abs((document.GetElementById(room2.LevelId) as Level).Elevation - elevation2) < CreateConduitFunction.approximate)
							{
								list.Add(room2);
							}
						}
					}
				}
			}
			if (list.Count < 1)
			{
				return false;
			}
			SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
			foreach (Room room3 in list)
			{
				List<RoomData.BoundingSegment> list2 = new List<RoomData.BoundingSegment>();
				foreach (IList<BoundarySegment> list3 in room3.GetBoundarySegments(spatialElementBoundaryOptions))
				{
					foreach (BoundarySegment segment in list3)
					{
						Element element3 = segment.GetElement(this.m_doc);
						if (element3 != null)
						{
							Curve curve = segment.GetCurve();
							curve.GetEndPoint(0);
							curve.GetEndPoint(1);
							RoomData.BoundingSegment item = new RoomData.BoundingSegment(curve, element3.Id);
							list2.Add(item);
						}
					}
				}
				RoomData item2 = new RoomData(list2, room3.Id);
				roomDataList.Add(item2);
			}
			return true;
		}

		private void RemoveRooms()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id).OfClass(typeof(SpatialElement));
			List<ElementId> list = new List<ElementId>();
			foreach (Element element in filteredElementCollector)
			{
				Room room = ((SpatialElement)element) as Room;
				if (room != null)
				{
					list.Add(room.Id);
				}
			}
			this.m_doc.Delete(list);
		}

		private List<RoomData> Create2ndGetRoomDataInfos(Level level, Document doc)
		{
			List<RoomData> list = new List<RoomData>();
			SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
			foreach (object obj in doc.get_PlanTopology(level).Circuits)
			{
				PlanCircuit planCircuit = (PlanCircuit)obj;
				if (!planCircuit.IsRoomLocated)
				{
					Room room = this.m_doc.Create.NewRoom(null, planCircuit);
					List<RoomData.BoundingSegment> list2 = new List<RoomData.BoundingSegment>();
					foreach (IList<BoundarySegment> list3 in room.GetBoundarySegments(spatialElementBoundaryOptions))
					{
						foreach (BoundarySegment segment in list3)
						{
							Element element = segment.GetElement(this.m_doc);
							if (element != null && !(element.GetType() != typeof(Wall)))
							{
								RoomData.BoundingSegment item = new RoomData.BoundingSegment(segment.GetCurve(), element.Id);
								list2.Add(item);
							}
						}
					}
					RoomData item2 = new RoomData(list2, room.Id);
					list.Add(item2);
				}
			}
			return list;
		}

		private static EquipmentComparer elementIDCompare = new EquipmentComparer();

		private UIDocument uiDoc;

		private Document m_doc;

		private ExternalCommandData m_cmdData;

		private static double approximate = 1E-05;

		public List<ConduitRouter> usedConduits = new List<ConduitRouter>();

		private List<Conduit> m_oldConduits = new List<Conduit>();

		private List<FamilyInstance> m_oldFittings = new List<FamilyInstance>();

		private List<FamilyInstance> m_GirderList = new List<FamilyInstance>();

		private double m_dThick;

		private double m_dWide;

		private bool m_isImproveDefultHigh;

		private List<Document> m_allLinkDocs = new List<Document>();

		private List<Wall> m_wallList = new List<Wall>();

		private List<Ceiling> m_CeilingList = new List<Ceiling>();

		private List<Floor> m_FloorList = new List<Floor>();

		private List<RoomData> m_roomList = new List<RoomData>();

		private List<RelationData> m_RelationDataList = new List<RelationData>();

		private int m_TopCelingDis = 200;

		private int m_BotFloorDis = 200;

		private int m_HighGroundDis = 50;

		public static HYCodeBase.WinForm.WindowHandle _hWndRevit = null;
	}
}
